#include "RingQueue.hpp"
#include <ctime>
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include "thread.h"
using namespace std;

#define C_SIZE 3
#define P_SIZE 5


void* Consume(void* argv)
{
    RingQueue<int>* rq = static_cast<RingQueue<int>*>(argv);
    while(1)
    {
        int data = rq->pop();
        printf("data: %d\n", data);
        sleep(2);
    }
    return nullptr; 
}

void* Produce(void* argv)
{
    RingQueue<int>* rq = static_cast<RingQueue<int>*>(argv);
    while(1)
    {
        int data = rand() % 100 + 1;
        rq->push(data);
        printf("Produce a data: %d\n", data);
        sleep(1);
    }

    return nullptr;
}

int main()
{
    srand(time(nullptr));
    RingQueue<int>* rq = new RingQueue<int>();
    // Thread c(Consume, rq);
    // Thread p(Produce, rq);

    // c.run();
    // p.run();

    // c.join();
    // p.join();


    vector<Thread> c(C_SIZE, Thread(Consume, rq));
    vector<Thread> p(P_SIZE, Thread(Produce, rq));
    
    for(int i = 0; i < C_SIZE; ++i)
    {
            c[i].run();
    }
    for(int i = 0; i < P_SIZE; ++i)
    {
            p[i].run();
    }
    for(int i = 0; i < C_SIZE; ++i)
    {
            c[i].join();
    }
    for(int i = 0; i < P_SIZE; ++i)
    {
            p[i].join();
    }



    return 0;
}



// int main()
// {
//     RingQueue<int>* rq = new RingQueue<int>;
//     vector<pthread_t> c_pid(C_SIZE);
//     vector<pthread_t> p_pid(P_SIZE);
//     srand(time(nullptr));
//     for(int i = 0; i < C_SIZE; ++i)
//     {
//         pthread_create(&c_pid[i], nullptr, Consume, rq);
//     }
//     for(int i = 0; i < P_SIZE; ++i)
//     {
//         pthread_create(&p_pid[i], nullptr, Produce, rq);
//     }

//     for(int i = 0; i < C_SIZE; ++i)
//     {
//         pthread_join(c_pid[i], nullptr);
//     }
//     for(int i = 0; i < P_SIZE; ++i)
//     {
//         pthread_join(p_pid[i], nullptr);
//     }

//     delete rq;
//     return 0;
// }
